package cn.juque.lucenecandy.threads;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.CalendarUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.juque.common.constants.YesOrNoEnum;
import cn.juque.lucenecandy.bo.IndexBO;
import cn.juque.lucenecandy.cache.IndexInfoCache;
import cn.juque.lucenecandy.core.constants.StrConstant;
import cn.juque.lucenecandy.helper.LuceneHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>ClearHideDocThreadPool</li>
 * </ul>
 * @date 2024-02-20
 **/
@Slf4j
@Component("clearHideDocThreadPool")
public class ClearHideDocThreadPool {

    private static final ThreadFactory THREAD_FACTORY = ThreadUtil.newNamedThreadFactory("clar-hiddoc-", true);

    private static final ScheduledExecutorService EXECUTOR =
            new ScheduledThreadPoolExecutor(1, THREAD_FACTORY, new ThreadPoolExecutor.DiscardPolicy());

    private Date lastRunTime = new Date();

    @Resource
    private IndexInfoCache indexInfoCache;

    @Resource
    private LuceneHelper luceneHelper;

    public void init() {
        EXECUTOR.scheduleWithFixedDelay(this::clear, 0, 10, TimeUnit.MINUTES);
        log.debug("success init clear hide doc ThreadPool");
    }

    private void clear() {
        Date curDate = new Date();
        if (DateUtil.betweenDay(lastRunTime, curDate, false) <= 0) {
            return;
        }
        if (DateUtil.compare(this.runTime(), curDate) > 0) {
            return;
        }
        Map<String, IndexBO> map = this.indexInfoCache.getAll();
        if (CollUtil.isEmpty(map)) {
            log.warn("清理隐藏文档时没能找到索引信息");
            return;
        }
        BooleanQuery.Builder builder = new BooleanQuery.Builder();
        builder.add(IntPoint.newExactQuery(StrConstant.D_VISIBLE, YesOrNoEnum.NO.getCode()), BooleanClause.Occur.MUST);
        map.forEach((k, v) -> {
            String indexName = v.getIndexName();
            this.luceneHelper.deleteDocuments(indexName, builder.build());
        });
        lastRunTime = new Date();
    }

    private Date runTime() {
        Calendar calendar = CalendarUtil.calendar();
        calendar.set(Calendar.HOUR_OF_DAY, 4);
        calendar.set(Calendar.MINUTE, 13);
        calendar.set(Calendar.SECOND, 3);
        return calendar.getTime();
    }
}
